home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / c / flash-0.4.3.lha / flash-0.4.3 / Lib / adpcm.cc next >
C/C++ Source or Header  |  1999-02-21  |  5KB  |  234 lines

  1. #include <assert.h>
  2. #include "adpcm.h"
  3.  
  4. static char *rcsid = "$Id: adpcm.cc,v 1.1 1998/08/31 21:52:39 olivier Exp $";
  5.  
  6. // This file has been rearranged from the code posted
  7. // on news:forums.macromedia.com by Jonathan Gay.
  8. // Courtesy of Macromedia
  9.  
  10. //
  11. // ADPCM tables
  12. //
  13.  
  14. static const int indexTable2[2] = {
  15.     -1, 2,
  16. };
  17.  
  18. // Is this ok?
  19. static const int indexTable3[4] = {
  20.     -1, -1, 2, 4,
  21. };
  22.  
  23. static const int indexTable4[8] = {
  24.     -1, -1, -1, -1, 2, 4, 6, 8,
  25. };
  26.  
  27. static const int indexTable5[16] = {
  28.  -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
  29. };
  30.  
  31. static const int* indexTables[] = {
  32.  indexTable2,
  33.  indexTable3,
  34.  indexTable4,
  35.  indexTable5
  36. };
  37.  
  38. static const int stepsizeTable[89] = {
  39.     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
  40.     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
  41.     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
  42.     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
  43.     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
  44.     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
  45.     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
  46.     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
  47.     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
  48. };
  49.  
  50. long
  51. Adpcm::GetBits(int n)
  52. {
  53.     if ( bitPos < n ) FillBuffer();
  54.  
  55.     assert(bitPos >= n);
  56.  
  57.     long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n);
  58.     bitPos -= n;
  59.  
  60.     return v;
  61. }
  62.  
  63. long
  64. Adpcm::GetSBits(int n)
  65. {
  66.     if ( bitPos < n ) FillBuffer();
  67.  
  68.     assert(bitPos >= n);
  69.  
  70.     long v = ((long)bitBuf << (32-bitPos)) >> (32-n);
  71.     bitPos -= n;
  72.  
  73.     return v;
  74. }
  75.  
  76. //
  77. // The Decompressor
  78. //
  79.  
  80. // Constructor
  81. Adpcm::Adpcm(unsigned char *buffer, long isStereo)
  82. {
  83.     stereo = isStereo;
  84.     src = buffer;
  85.  
  86.     nBits = 0; // flag that it is not inited
  87.     nSamples = 0;
  88.  
  89.     bitPos = 0;
  90.     bitBuf = 0;
  91. }
  92.  
  93. void
  94. Adpcm::FillBuffer()
  95. {
  96.     while ( bitPos <= 24 /*&& srcSize > 0*/ ) {
  97.         bitBuf = (bitBuf<<8) | *src++;
  98.         bitPos += 8;
  99.     }
  100. }
  101.  
  102. void
  103. Adpcm::Decompress(short *dst, long n)
  104. {
  105.     if ( nBits == 0 ) {
  106.         // Get the compression header
  107.         nBits = (int)GetBits(2)+2;
  108.     }
  109.  
  110.     const int* indexTable = indexTables[nBits-2];
  111.     int k0 = 1 << (nBits-2);
  112.     int signmask = 1 << (nBits-1);
  113.  
  114.     if ( !stereo ) {
  115.         // Optimize for mono
  116.         long        vp = valpred[0]; // maybe these can get into registers...
  117.         int        ind = index[0];
  118.         long        ns = nSamples;
  119.  
  120.         while ( n-- > 0 ) {
  121.             ns++;
  122.  
  123.             if ( (ns & 0xFFF) == 1 ) {
  124.                 // Get a new block header
  125.                 *dst++ = (short)(vp = GetSBits(16));
  126.  
  127.                 ind = (int)GetBits(6); // The first sample in a block does not have a delta
  128.             } else {
  129.                 // Process a delta value
  130.                 int delta = (int)GetBits(nBits);
  131.  
  132.                 // Compute difference and new predicted value
  133.                 // Computes 'vpdiff = (delta+0.5)*step/4'
  134.                 int step = stepsizeTable[ind];
  135.                 long vpdiff = 0;
  136.                 int k = k0;
  137.  
  138.                 do {
  139.                     if ( delta & k )
  140.                     vpdiff += step;
  141.                     step >>= 1;
  142.                     k >>= 1;
  143.                 } while ( k );
  144.  
  145.                 vpdiff += step; // add 0.5
  146.  
  147.                 if ( delta & signmask ) // the sign bit
  148.                     vp -= vpdiff;
  149.                 else
  150.                     vp += vpdiff;
  151.  
  152.                 // Find new index value
  153.                 ind += indexTable[delta&(~signmask)];
  154.  
  155.                 if ( ind < 0 )
  156.                     ind = 0;
  157.                 else if ( ind > 88 )
  158.                     ind = 88;
  159.  
  160.                 // clamp output value
  161.                 if ( vp != (short)vp )
  162.                     vp = vp < 0 ? -32768 : 32767;
  163.  
  164.                 /* Step 7 - Output value */
  165.                 *dst++ = (short)vp;
  166.             }
  167.         }
  168.  
  169.         valpred[0] = vp;
  170.         index[0] = ind;
  171.         nSamples = ns;
  172.  
  173.     } else {
  174.         int sn = stereo ? 2 : 1;
  175.  
  176.         // Stereo
  177.         while ( n-- > 0 ) {
  178.  
  179.             nSamples++;
  180.  
  181.             if ( (nSamples & 0xFFF) == 1 ) {
  182.                 // Get a new block header
  183.                 for ( int i = 0; i < sn; i++ ) {
  184.  
  185.                     *dst++ = (short)(valpred[i] = GetSBits(16));
  186.  
  187.                     // The first sample in a block does not have a delta
  188.                     index[i] = (int)GetBits(6);
  189.                 }
  190.             } else {
  191.                 // Process a delta value
  192.                 for ( int i = 0; i < sn; i++ ) {
  193.                     int delta = (int)GetBits(nBits);
  194.  
  195.                     // Compute difference and new predicted value
  196.                     // Computes 'vpdiff = (delta+0.5)*step/4'
  197.  
  198.                     int step = stepsizeTable[index[i]];
  199.                     long vpdiff = 0;
  200.                     int k = k0;
  201.  
  202.                     do {
  203.                         if ( delta & k ) vpdiff += step;
  204.                         step >>= 1;
  205.                         k >>= 1;
  206.                     } while ( k );
  207.                     vpdiff += step; // add 0.5
  208.  
  209.  
  210.                     if ( delta & signmask ) // the sign bit
  211.                         valpred[i] -= vpdiff;
  212.                     else
  213.                         valpred[i] += vpdiff;
  214.  
  215.                     // Find new index value
  216.                     index[i] += indexTable[delta&(~signmask)];
  217.  
  218.                     if ( index[i] < 0 )
  219.                         index[i] = 0;
  220.                     else if ( index[i] > 88 )
  221.                         index[i] = 88;
  222.  
  223.                     // clamp output value
  224.                     if ( valpred[i] != (short)valpred[i] )
  225.                         valpred[i] = valpred[i] < 0 ? -32768 : 32767;
  226.  
  227.                     /* Step 7 - Output value */
  228.                     *dst++ = (short)valpred[i];
  229.                 }
  230.             }
  231.         }
  232.     }
  233. }
  234.